class Bluetooth {

	constructor() {
		this.isOpenBle = false;
		this.deviceId = "";
		this.serviceId = "";
		this.writeId = "";
		this.notifyId = "";
		this.openBluetoothAdapter();
	}

	showToast(title) {
		uni.showToast({
			title: title,
			icon: 'none',
			'duration': 2000
		});
	}
    //初始化蓝牙模块，检查蓝牙是否已打开
	openBluetoothAdapter() {
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				success: res => {
					this.isOpenBle = true;
					resolve(res);
				},
				fail: err => {
					setTimeout(function() {
						uni.showToast({
							title:"请打开蓝牙和定位功能",
							icon:"none"
						})
					}, 1000);
					reject(err);
				},
			});
		});
	}
    //搜索周边蓝牙设备
	startBluetoothDevicesDiscovery() {
		if (!this.isOpenBle) {
			this.showToast(`请打开蓝牙和定位功能`)
			return;
		}

		let self = this;
		uni.showLoading({
			title: '正在搜索蓝牙设备'
		})
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.startBluetoothDevicesDiscovery({
					success: res => {
						resolve(res)
					},
					fail: res => {
						self.showToast(`搜索设备失败` + JSON.stringify(err));
						reject(err);
					}
				})
			}, 300);
		});
	}
    //停止搜索周报蓝牙设备
	stopBluetoothDevicesDiscovery() {
		let self = this;
		return new Promise((resolve, reject) => {
			uni.stopBluetoothDevicesDiscovery({
				success: e => {
					uni.hideLoading();
				},
				fail: e => {
					uni.hideLoading();
					self.showToast('停止搜索失败，请重试');
				}
			})
		});
	}
    //连接设备
	createBLEConnection() {
		let deviceId = this.deviceId;
		let self = this;

		return new Promise((resolve, reject) => {
			uni.createBLEConnection({
				deviceId,
				success: (res) => {
					console.log("成功连接设备" + JSON.stringify(res));
					resolve(res)
				},
				fail: err => {
					self.showToast(`设备连接失败` + JSON.stringify(err));
					reject(err);
				}
			})
		});
	}

	//获取蓝牙设备所有服务(service)
	getBLEDeviceServices() {
		let _serviceList = [];
		let deviceId = this.deviceId;
		let self = this;

		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.getBLEDeviceServices({
					deviceId,
					success: res => {
						//console.log('获取服务成功');
						//console.log(res.services);
						for (let service of res.services) {
							if (service.isPrimary) {
								_serviceList.push(service);
							}
						}
						if(res.services.length<=0){
							self.showToast('成功获取服务，但没有可用服务');
						}
						
						resolve(_serviceList)
					},
					fail: err => {
						//设备已连接，但未能获取设备服务，也有可能连接处于断开状态
						self.showToast('未获取蓝牙设备相关服务');
						reject(err);
					},
				})
			}, 2000);
		});
	}

	//获取蓝牙设备某个服务中所有特征值(characteristic)
	getBLEDeviceCharacteristics() {
		let deviceId = this.deviceId;
		let serviceId = this.serviceId;

		let self = this;
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success: res => {
					for (let _obj of res.characteristics) {
						//获取notify
						if (_obj.properties.notify) {
							self.notifyId = _obj.uuid;
							uni.setStorageSync('notifyId', self.notifyId);
						}
						//获取writeId
						if (_obj.properties.write) {
							self.writeId = _obj.uuid;
							uni.setStorageSync('writeId', self.writeId);
						}
					}

					let result = {
						'notifyId': self.notifyId,
						'writeId': self.writeId
					};
					//成功获取到设备的服务特征值，可以测试设备功能了
					//self.showToast('已获取打印机服务，请测试打印功能')
					resolve(result)
				},
				fail: err => {
					//已连接设备，但未能获取设备服务
					self.showToast('未能获取设备相关服务，请重试')
					reject(err);
				}
			})
		});
	}

	//断开蓝牙链接
	closeBLEConnection() {
		let deviceId = this.deviceId;
		uni.closeBLEConnection({
			deviceId,
			success(res) {
				console.log('蓝牙连接已断开')
			}
		})
	}
    //启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值
	notifyBLECharacteristicValue() {
		let deviceId = this.deviceId;
		let serviceId = this.serviceId;
		let characteristicId = this.notifyId;
        //特征值变化时，异步通知提示
		uni.notifyBLECharacteristicValueChange({
			state: true, // 启用 notify 功能
			deviceId,
			serviceId,
			characteristicId,
			success(res) {
				//监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification
				uni.onBLECharacteristicValueChange(function(res) {

				});
			},
			fail(res) {
				console.log('notifyBLECharacteristicValueChange failed:' + res.errMsg);

			}
		});
	}
    //向低功耗蓝牙设备特征值中写入二进制数据。注意：必须设备的特征值支持 write 才可以成功调用
	writeBLECharacteristicValue(buffer) {
		let deviceId = this.deviceId;
		let serviceId = this.serviceId;
		let characteristicId = this.writeId;

		//console.log("当前连接蓝牙设备服务信息: " + JSON.stringify(this));

		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId,
				serviceId,
				characteristicId,
				value: buffer,
				success(res) {
					//console.log('message发送成功', JSON.stringify(res));
					resolve(res);
				},
				fail(err) {
					console.log('message发送失败', JSON.stringify(err));
					reject(err);
				}
			});
		});
	}

    //关闭蓝牙连接，想要连接要重新启动
	closeBluetoothAdapter() {
		uni.closeBluetoothAdapter({
			success: res => {
				//console.log(res)
			}
		});
	}

	//若APP在之前已有搜索过某个蓝牙设备，并成功建立连接，可直接传入之前搜索获取的 deviceId 直接尝试连接该设备，无需进行搜索操作。
	reconnect() {
		(async () => {
			try {
				this.deviceId = this.deviceId || uni.getStorageSync("deviceId");//设备id
				this.serviceId = this.serviceId || uni.getStorageSync("serviceId");//服务id
				this.notifyId = this.notifyId || uni.getStorageSync("notifyId");//
				this.writeId = this.writeId || uni.getStorageSync("writeId");//写入二进制数据 特征值id
                //连接蓝牙设备
				await this.createBLEConnection();
                //获取蓝牙设备服务
				//await this.getBLEDeviceServices();
               
				uni.hideLoading()
				if(!this.serviceId || this.serviceId == ''){
					//this.showToast('打印服务已断开，请到开发设置重新搜索蓝牙设备')
					uni.showModal({
						title: '打印机断开提示',
						content: '打印服务已断开，请到开发设置重新搜索蓝牙设备'
					});
				}else if(!this.writeId || this.writeId == ''){
					//重新获取蓝牙设备服务特征值
					await this.getBLEDeviceCharacteristics();
					this.showToast('成功连接打印机')
				}else {
					this.showToast('成功连接打印机')
				}
				
			} catch (err) {
				uni.hideLoading()
				console.log("err: " + JSON.stringify(err));
			}

		})();
	}
}

export default Bluetooth;
